home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <osbind.h>
- #include <string.h>
- #include <ctype.h>
-
- #ifdef __GNUC__
- /* minimal stuff */
-
- #include <minimal.h>
- #include <stdarg.h>
-
- int printf(const char *fmt,...)
- {
- va_list args;
- char buf[128];
- va_start(args,fmt);
- vsprintf(buf,fmt,args);
- Cconws(buf);
- return 0;
- }
-
- #undef putchar
- #define putchar(c) Cconout(c)
- #endif
-
- #define TRUE 1
- #define FALSE 0
-
- #define DRV_CHAR ':'
- #define PATH_CHAR '\\'
-
- extern char *syserr(long);
-
- struct _dta *dtas = 0;
- int nfiles = 0;
- int nalloc = 0;
-
- int lflag = 0, fflag = 0, aflag = 0, rflag = 0, tflag = 0;
-
- int cmpname(const struct _dta *a, const struct _dta *b)
- {
- return strcmp(a->dta_name,b->dta_name);
- }
-
- int cmptime(const struct _dta *a, const struct _dta *b)
- {
- unsigned long datime1, datime2;
- datime1 = ((unsigned long)a->dta_date) << 16 |
- (unsigned long)a->dta_time;
- datime2 = ((unsigned long)b->dta_date) << 16 |
- (unsigned long)b->dta_time;
- if (datime1 > datime2) return -1;
- else if (datime1 == datime2) return 0;
- else return 1;
- }
-
- void
- add_file(struct _dta *dta)
- {
- if (dtas == 0) {
- dtas = malloc(10 * sizeof(struct _dta));
- nalloc = 10;
- nfiles = 0;
- }
- else if (nalloc == nfiles) {
- nalloc += 10;
- if ((dtas = realloc(dtas,nalloc * sizeof(struct _dta))) == NULL) {
- printf("Out of memory\r\n");
- Pterm(1);
- }
- }
- dtas[nfiles] = *dta;
- nfiles++;
- }
-
- void
- downcase(char *s)
- {
- while (*s) {
- if (isupper(*s)) *s = tolower(*s);
- s++;
- }
- }
-
- char *suffixes[] = { ".ttp", ".prg", ".tos", ".app" };
- #define NSUFFIXES (sizeof(suffixes) / sizeof(char *))
-
- inline int
- isexec(char *s)
- {
- int i;
- for (i = NSUFFIXES; --i >= 0; ) {
- if (strstr(s,suffixes[i])) return 1;
- }
- return 0;
- }
-
- void
- do_dir(const char *name) {
- char buf[128]; /* requested path ends up here */
- char *temp;
- struct _dta *odta = (struct _dta *)Fgetdta();
- struct _dta dta;
- char *p;
- int i, j, k, n, nrows;
- int dflag;
- long e;
- struct _dta *s;
- int (*cmpfn)(const void *,const void *);
-
- strcpy(buf,name);
- temp = buf;
- while (*temp) temp++;
-
- /* if arg ends with a backslash, slash, or colon, add "*.*" to it */
- if (*(temp-1) == DRV_CHAR || *(temp-1) == PATH_CHAR) {
- strcpy(temp,"*.*");
- dflag=TRUE; /* dflag says this is a directory */
- }
- else dflag = FALSE;
-
- /* if the name has no wildcards, find the file. */
- /* if it turns out to be a directory, add "\*.*" to it */
-
- (void)Fsetdta(&dta);
- if ((strchr(buf,'*') == NULL) && (strchr(buf,'?') == NULL)) {
- /* no wildcards */
- if ((e = Fsfirst(buf,-1)) < 0) {
- printf("%s: %s\r\n",buf,syserr(e));
- goto reallydone;
- }
- else {
- /* found the file: is it a directory? */
- if (dta.dta_attribute & 0x10) {
- /* directory: add \*.* to it */
- /* \\ below should be PATH_CHAR */
- strcpy(temp,"\\*.*");
- temp++;
- }
- else {
- /* no wildcards, file exists, not a directory: unique */
- downcase(dta.dta_name);
- add_file(&dta);
- goto gotfiles;
- }
- }
- }
-
- /* do the Fsfirst again because buf may have changed */
- if ((e = Fsfirst(buf,-1)) < 0) {
- if (dflag) printf("no files\r\n");
- else printf("%s: %s\r\n",buf,syserr(e));
- goto reallydone;
- }
- n = 0;
-
- do {
- /* add the file to the list of files */
- /* add all files if aflag, else skip those with leading dots */
- if (aflag || *(dta.dta_name) != '.') {
- downcase(dta.dta_name);
- add_file(&dta);
- }
- } while (Fsnext() == 0);
-
- if (nfiles == 0) {
- printf("no files\r\n");
- goto reallydone;
- }
-
- /* I hate this messy cast... */
- cmpfn = (tflag ? (int (*)(const void *,const void *))cmptime
- : (int (*)(const void *,const void *))cmpname);
- qsort(dtas,(size_t)nfiles,sizeof(struct _dta),cmpfn);
-
- gotfiles:
- if (lflag) {
- for (i = 0, s = dtas; i < nfiles; s++, i++) {
- printf("%02x %02d/%02d/%02d %02d:%02d:%02d %8ld %s%c\r\n",
- s->dta_attribute,
- (s->dta_date >> 9) + 80,
- (s->dta_date >> 5) & 0xf,
- (s->dta_date) & 0x1f,
-
- (s->dta_time >> 11),
- (s->dta_time >> 5) & 0x3f,
- (s->dta_time & 0x1f),
- s->dta_size,
- s->dta_name,
- (!fflag ? ' ' : ((s->dta_attribute & 0x10 ? '\\' :
- (isexec(s->dta_name) ? '*' : ' ')))));
- }
- }
- else {
-
- #define NCOLS 5
-
- /* output in 5-column format */
- nrows = (nfiles + (NCOLS-1)) / NCOLS;
- for (i = 0; i < nrows; i++) {
- s = &dtas[i];
- for (j = 0; j < NCOLS; j++, s += nrows) {
- if (s >= &dtas[nfiles]) {
- printf("\r\n");
- break;
- }
- printf("%s",s->dta_name);
- k = strlen(s->dta_name);
- if (fflag) {
- if (s->dta_attribute & 0x10) {
- putchar('\\');
- k++;
- }
- else if (isexec(s->dta_name)) {
- putchar('*');
- k++;
- }
- }
- /* don't output tab(s) after the last name on a line */
- if (j < (NCOLS-1)) {
- if (k<8) putchar('\t');
- putchar('\t');
- }
- else printf("\r\n");
- }
- }
- }
-
- if (dtas) {
- free(dtas);
- dtas = NULL;
- nalloc = 0;
- nfiles = 0;
- }
- if (rflag) {
- /* Do another Fsfirst/Fsnext pass for directories. */
- /* Remember, buf has the Fsfirst target. */
- /* Set temp just past the last PATH_CHAR or DIR_CHAR. */
-
- if ((temp = strrchr(buf,PATH_CHAR)) == NULL) temp = buf;
- else temp++;
-
- if ((p = strrchr(temp,DRV_CHAR)) != NULL) temp = p+1;
-
- if (Fsfirst(buf,-1) < 0) goto reallydone;
- do {
- if (dta.dta_attribute & 0x10 && *dta.dta_name != '.') {
- strcpy(temp,dta.dta_name);
- downcase(buf);
- printf("\r\n%s:\r\n",buf);
- do_dir(buf);
- }
- } while (!Fsnext());
- }
-
- reallydone:
- (void)Fsetdta(odta);
- }
-
- int
- main(int argc,char *argv[])
- {
- char *p;
- --argc, ++argv;
- while (*argv && **argv == '-') {
- p = &argv[0][1];
- while (*p) {
- switch (*p) {
- case 'l': lflag = 1; break;
- case 'F': fflag = 1; break;
- case 'a': aflag = 1; break;
- case 'R': rflag = 1; break;
- case 't': tflag = 1; break;
- default:
- printf("Unknown option: %s\r\n",*p);
- printf("Usage: ls [-aFlRt] [files ...]\r\n");
- exit(1);
- }
- p++;
- }
- argc--, argv++;
- }
-
- if (!argc) {
- argc = 1;
- *argv = "*.*";
- }
-
- while (argc) {
- do_dir(*argv);
- argv++, argc--;
- if (argc) printf("\r\n");
- }
- exit(0);
- }
-
-